package com.pi.shisan.service.service.impl;

import com.alibaba.fastjson2.JSON;
import com.pi.shisan.service.constants.HttpHeadVal;
import com.pi.shisan.service.domain.LedClockHoliday;
import com.pi.shisan.service.dto.NextVacationDTO;
import com.pi.shisan.service.dto.from.VacationDTO;
import com.pi.shisan.service.mapper.ClockHolidayMapper;
import com.pi.shisan.service.service.GovHolidayService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class GovHolidayServiceImpl implements GovHolidayService {

    @Autowired
    private HttpClient httpClient;

    @Autowired
    private ClockHolidayMapper clockHolidayMapper;

    @Value("${tianapi.holiday.key:}")
    private String key;

    @Override
    public boolean refresh() {
        LocalDate now = LocalDate.now();
        int year = now.getYear();
        boolean hasNew = false;
        if (clockHolidayMapper.checkHasYearInfo(year) == null) {
            forceRefresh(year);
            hasNew = true;
        }
        if (now.getMonthValue() == 12 && now.getDayOfMonth() >= 30) {
            year++;
            if (clockHolidayMapper.checkHasYearInfo(year) == null) {
                forceRefresh(year);
                hasNew = true;
            }
        }
        return hasNew;
    }

    @Override
    public void forceRefresh(Integer year) {
        if (StringUtils.isBlank(key)) {
            return;
        }
        HttpGet get = new HttpGet("http://api.tianapi.com/jiejiari/index?key="+key+"&type=1&date="+year);
        get.setHeader(HttpHeaders.USER_AGENT, HttpHeadVal.USER_AGENT_VAL);
        try {
            HttpResponse response = httpClient.execute(get);
            try {
                if (response.getStatusLine().getStatusCode() == 200) {
                    HttpEntity entity = response.getEntity();
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    entity.writeTo(bos);
                    String json = new String(bos.toByteArray(), StandardCharsets.UTF_8);
                    readFromJson(json);
                } else {
                    throw new RuntimeException("获取数据错误，返回："+response.getStatusLine().getStatusCode());
                }
            } catch (RuntimeException e) {
                EntityUtils.consume(response.getEntity());
            }
        } catch (IOException e) {
            log.error("获取节假日信息失败：",e);
        }
    }

    @Override
    public List<NextVacationDTO> allNextVacation(LocalDate date) {
        return getNext(date,1);
    }

    @Override
    public List<NextVacationDTO> allNextOffice(LocalDate date) {
        return getNext(date,2);
    }

    private synchronized List<NextVacationDTO> getNext(LocalDate date,Integer dayType) {
        List<LedClockHoliday> list = clockHolidayMapper.selectNext(date.getYear() * 10000 + date.getMonthValue() * 100 + date.getDayOfMonth(), dayType);
        if (list != null && list.size() > 0) {
            return list.stream().map(
                    h->{
                        NextVacationDTO v = new NextVacationDTO();
                        v.setName(h.getHolidayName());
                        v.setDayint(h.getDayint());
                        return v;
                    }
            ).collect(Collectors.toList());
        }
        return null;
    }

    private void readFromJson(String json) {
        VacationDTO result = JSON.parseObject(json, VacationDTO.class);
        if (result.getCode() == 200) {
            List<VacationDTO.HolidayInfo> holidayList = result.getHolidayList();
            if (holidayList != null) {
                for (VacationDTO.HolidayInfo info : holidayList) {
                    if (StringUtils.isNotBlank(info.getVacation())) {
                        createHolidayInfo(info.getVacation(), info.getName(), 1);
                    }
                    if (StringUtils.isNotBlank(info.getRemark())) {
                        createHolidayInfo(info.getRemark(), info.getName(), 2);
                    }
                }
            }
        } else {
            throw new RuntimeException("获取节假日失败，节假日接口返回："+ JSON.toJSONString(json));
        }
    }

    private void createHolidayInfo(String info, String name, int holidayType) {
        String[] days = info.split("\\|");
        for (String dayStr : days) {
            String[] date = dayStr.split("-");
            int year = Integer.parseInt(date[0]);
            int month = Integer.parseInt(date[1]);
            int day = Integer.parseInt(date[2]);
            LedClockHoliday holiday = new LedClockHoliday();
            holiday.setHolidayName(name);
            holiday.setDayint(year * 10000 + month* 100 + day);
            holiday.setDayType(holidayType);
            holiday.setClkYear(year);
            clockHolidayMapper.insert(holiday);
        }
    }
}
